#ifndef AUTHGUY_H
#define AUTHGUY_H


// From bnetd.
#ifndef ROTL
  //===
  // There were some problems with this optimization under Darwin.
  // #define ROTL(x,n,w) (((n)%(w)) ? (((x)<<((n)%(w))) | ((x)>>((w)-((n)%(w))))) : (x))
#define ROTL(x,n,w) (((x)<<((n)&(w-1))) | ((x)>>(((-(n))&(w-1))))) 
#endif
#ifndef ROL
#define ROL(x,n) ROTL(x,n,32)
#endif
//////////////////////////////////////////////////////////////////////////////

#include "src/conGuy/types.h"
#include <string>



using namespace std;



class authGuy {
 public:
  authGuy();
  ~authGuy();


  // CD KEY STUFF
  bool getCDVars();
  u32 getCdkeyVar0() { return cdkeyVar0; }
  u32 getCdkeyVar1() { return cdkeyVar1; }
  u32 getCdkeyVar2() { return cdkeyVar2; }
  
  // The GET functions
  u32 getServerToken() { return serverToken; }
  u32 getClientToken() { return clientToken; }
  u32 checkRevision();
  u32 *getHashData();
  u32 *getPasswordHash();  // sizeof(u32) * 5
  string getExeInfo();
  string getAccount() { return account; }


  // The SET functions.
  void setLogonType(const u32 newVal)   { logonType = newVal; }
  void setServerToken(const u32 newVal) { serverToken = newVal; }
  void setUdpValue(const u32 newVal)    { udpValue = newVal; }
  void setHash_mpq(const char* newVal) { strcpy(hash_mpq, newVal); }
  void setHash_equ(const char* newVal) { strcpy(hash_equ, newVal); }
  void setHashfile1(const string file1) { f1 = file1; }
  void setHashfile2(const string file2) { f2 = file2; }
  void setHashfile3(const string file3) { f3 = file3; }
  void setAccount(const string acc) { account = acc; }
  void setPassword(const string pwd) { password = pwd; }
  void setCdkey(const string _cdkey) { cdkey = _cdkey; }

 private:
  u32 client;
  u32 logonType;     // Logon Type.  (0 == Broken Sha-1 (STAR/SEXP/D2DV/D2XP)
                     //               1 == NLS version 1 (War3Beta),
                     //               2 == NLS Version 2 (WAR3))
  u32 serverToken;
  u32 clientToken;
  u32 udpValue;       // We won't use this.  See note below.

  char hash_mpq[64];   // We extract the mpq ver from this.
  char hash_equ[128];   // This contains the equation.
  
  u32 cdkeyVar0;  // cdkey variables
  u32 cdkeyVar1;
  u32 cdkeyVar2;

  u32 hash_data[5];  // This is the hashed data after a hash algorithm.
  u32 hash_password[5]; // This is the hashed data after the double-hashing
                        // of the password & tokens.
  
  // Note about udpValue:
  //   No one really knows what this is, however, it is used in 2nd DWORD of 
  //   the UDP packet PKT_CONNTEST2 (0x09). It has also been seen in the realm 
  //   logon blob.  PKT_CONNTEST2 is used to establish that the client supports
  //   UDP.

  
  u32 uatol( char *s);  // The default atol does not work because 
                        //   our input is unsigned.

  string f1;  // Hash file filenames.
  string f2;
  string f3;
  
  string account;
  string password;
  string cdkey;

  // CHECK REVISION STUFF
  //   int checkRevision( u32 client, char *equ, int mpq, u32 *var, 
  // 		     const char *f1, const char *f2, const char *f3);
  int checkRevision( u32 client, char *equ, unsigned int mpq, u32 *var, 
		     const char *f1, const char *f2, const char *f3);

  // CD KEY STUFF
  void decodeStar( char *cdkey);

  // HASHING STUFF.
  void sha1_hash( const char *src, int len, char *dest);
  
  int tohex(u32 i);
  int fromhex(char ch);
};





#endif
